package org.stvd.repository.admin.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Repository;
import org.stvd.core.dto.QueryResult;
import org.stvd.core.util.StringUtil;
import org.stvd.entities.admin.Department;
import org.stvd.entities.admin.UserDep;
import org.stvd.repository.admin.DepartmentDao;
import org.stvd.repository.base.impl.BaseDaoImpl;

@Repository("DepartmentDao")
public class DepartmentDaoImpl extends BaseDaoImpl<Department> implements DepartmentDao {

    @Override
    public List<Department> findAllDepByUid(String userId) {
        String hql = " SELECT T1 FROM Department T1, UserDep T2 WHERE T2.userId = ?0 AND T1.depId =T2.depId ";
        return findByHQL(hql, userId);
    }
    
    @Override
    public List<Department> findAllDepByGuid(String guid) {
        return findByHQL("FROM Department WHERE guid = ?0 ", guid);
    }
    
    @Override
    public List<Department> findImeDepartmentByJsm(String jsm, String guid) {
        return findByHQL("from Department T where T.jsm like ?0 AND T.guid = ?1", jsm, guid);
    }

    @Override
    public void insertUserDep(String userId, String depId, String guid) {
        em.createQuery("delete from UserDep T where T.userId = :userId and T.guid = :guid ")
        .setParameter("userId", userId)
        .setParameter("guid", guid)
        .executeUpdate();
        em.flush();
        if (depId != null) {
            UserDep userdepTmp = new UserDep();
            userdepTmp.setId(StringUtil.getRandomUUID());
            userdepTmp.setDepId(depId);
            userdepTmp.setUserId(userId);
            userdepTmp.setGuid(guid);
            em.persist(userdepTmp);
        }
    }
 
    @Override
    public List<Department> findDepByUid(String userId, String guid) {
        return findByHQL("select T1 from Department T1, UserDep T2 "
            + " where T1.depId = T2.depId and T2.userId = ?0 and T1.guid = ?1", userId, guid);
    }

    @Override
    public QueryResult<Department> getDepartmentQueryResult(int start, int limit, String depName, String guid) {
        String hql = "from Department T where T.guid = ?0 and T.depName like ?1";
        return getQueryResultByHQL(start, limit, hql, guid, "%"+depName+"%");
    }

    @Override
    public List<Department> getChildDepartment(String depId, String guid) {
        return findByHQL("from Department T where T.upperId=?0 and T.guid = ?1", depId, guid);
    }

    @Override
    public List<Department> getAllChildDepartment(String depId, String guid) {
        List<Department> list = new ArrayList<Department>();
        Department department = this.findByPk(Department.class, depId);
        if (department != null) {
            list = findDepartmentByInnerCode(department.getInnerCode(), guid);
        }
        return list;
    }

    @Override
    public List<Department> findDepartmentByInnerCode(String innerCode, String guid) {
        return findByHQL("from Department T where T.innerCode like ?0 and T.guid = ?1 order by T.depCode", innerCode+"%", guid);
    }

    @Override
    public Department getDepartmentByDepCode(String depCode, String guid) {
        List<Department> list = findByHQL("FROM Department WHERE depCode = ?0 AND guid = ?1", depCode, guid);
        if(list!=null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public List<Map<String, Object>> listUserNoneDepGuid(String userId, String depCode) {
        String sql = " SELECT guid, dep_id FROM department WHERE dep_code = :depCode AND guid NOT IN ("
               + " SELECT T1.guid from user_dep T1, department T2 WHERE T1.dep_id = T2.dep_id "
               + " AND T1.user_id = :userId AND T2.dep_code = :depCode )";
       Map<String, Object> params = new HashMap<>();
       params.put("userId", userId);
       params.put("depCode", depCode);
       return findBySQLToMap(0, 0, sql, params);
    }

    @Override
    public List<Map<String, Object>> listUserDepByGuid(String guid) {
        String sql = "SELECT dp.dep_id, dp.dep_name, dp.dep_code, ud.user_id FROM "
            + " department dp, user_dep ud WHERE dp.dep_id = ud.dep_id AND ud.guid = :guid";
        Map<String, Object> params = new HashMap<>();
        params.put("guid", guid);
        return findBySQLToMap(sql, params);
    }
}
